package cn.com.easy.permission.web.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 对请求参数进行trim，去除左右空格和换行符等
 * 
 * @author nibili 2017年9月23日
 * 
 */
@Component
public class ParameterTrimFilter extends OncePerRequestFilter {

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper(request);
		filterChain.doFilter(requestWrapper, response);
	}

	/**
	 * 请求参数的wrapper
	 * 
	 * @author nibili 2017年9月23日
	 * 
	 */
	public static class ParameterRequestWrapper extends HttpServletRequestWrapper {
		/** 参数集合 */
		private Map<String, String[]> params = new HashMap<String, String[]>();

		public ParameterRequestWrapper(HttpServletRequest request) {
			// 将request交给父类，以便于调用对应方法的时候，将其输出，其实父亲类的实现方式和第一种new的方式类似
			super(request);
			// 将参数表，赋予给当前的Map以便于持有request中的参数
			this.params.putAll(request.getParameterMap());
			this.modifyParameterValues();
		}

		// 重载一个构造方法
		public ParameterRequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) {
			this(request);
			addAllParameters(extendParams);// 这里将扩展参数写入参数表
		}

		public void modifyParameterValues() {// 将parameter的值去除空格后重写回去
			Set<String> set = params.keySet();
			Iterator<String> it = set.iterator();
			while (it.hasNext()) {
				String key = (String) it.next();
				String[] values = params.get(key);
				values[0] = values[0].trim();
				params.put(key, values);
			}
		}

		@Override
		public String getParameter(String name) {// 重写getParameter，代表参数从当前类中的map获取
			String[] values = params.get(name);
			if (values == null || values.length == 0) {
				return null;
			}
			return values[0];
		}

		public String[] getParameterValues(String name) {// 同上
			return params.get(name);
		}

		public void addAllParameters(Map<String, Object> otherParams) {// 增加多个参数
			for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
				addParameter(entry.getKey(), entry.getValue());
			}
		}

		public void addParameter(String name, Object value) {// 增加参数
			if (value != null) {
				if (value instanceof String[]) {
					params.put(name, (String[]) value);
				} else if (value instanceof String) {
					params.put(name, new String[] { (String) value });
				} else {
					params.put(name, new String[] { String.valueOf(value) });
				}
			}
		}
	}
}